home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / oleo130s.zip / OLEO130S.TAR / oleo-1.3 / io-curses.c < prev    next >
C/C++ Source or Header  |  1993-03-30  |  22KB  |  1,261 lines

  1. /*    Copyright (C) 1992, 1993 Free Software Foundation, Inc.
  2.  
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2, or (at your option)
  6. any later version.
  7.  
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11. GNU General Public License for more details.
  12.  
  13. You should have received a copy of the GNU General Public License
  14. along with this software; see the file COPYING.  If not, write to
  15. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  16.  
  17.  
  18. #include "proto.h"
  19. #include "funcdef.h"
  20. #include <stdio.h>
  21. #include <curses.h>
  22. #include <fcntl.h>
  23. #include <errno.h>
  24. #include <ctype.h>
  25. #include <signal.h>
  26. #undef NULL
  27. #include "sysdef.h"
  28. #include "global.h"
  29. #include "cell.h"
  30. #include "cmd.h"
  31. #include "line.h"
  32. #include "io-generic.h"
  33. #include "io-edit.h"
  34. #include "io-term.h"
  35. #include "io-abstract.h"
  36. #include "io-utils.h"
  37. #include "lists.h"
  38. #include "regions.h"
  39. #include "window.h"
  40. #include "key.h"
  41. #include "input.h"
  42. #include "info.h"
  43.  
  44. #define MIN_WIN_HEIGHT    (cwin->flags&WIN_EDGES ? 2 : 1)
  45. #define MIN_WIN_WIDTH    (cwin->flags&WIN_EDGES ? 6 : 1)
  46.  
  47. static int redrew = 0;
  48. static int textout = 0;
  49. static int term_cursor_claimed = 0;
  50.  
  51. #ifdef __STDC__
  52. static void move_cursor_to (struct window *, CELLREF, CELLREF, int);
  53. #else
  54. static void move_cursor_to ();
  55. #endif
  56.  
  57.  
  58. #ifdef __STDC__
  59. static int
  60. curses_metric (char * str, int len)
  61. #else
  62. static int
  63. curses_metric (str, len)
  64.      char * str;
  65.      int len;
  66. #endif
  67. {
  68.   return len;
  69. }
  70.  
  71. static struct input_view input_view
  72.   = {0, curses_metric, curses_metric, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  73.  
  74. #ifdef __STDC__
  75. static void
  76. _io_redraw_input (void)
  77. #else
  78. static void
  79. _io_redraw_input ()
  80. #endif
  81. {
  82.   int pos;
  83.   int row = (input_view.current_info ? 1 : input);
  84.  
  85.   if (input_view.info_redraw_needed)
  86.     {
  87.       input_view.info_redraw_needed = 0;
  88.       io_repaint ();
  89.       return;
  90.     }
  91.  
  92.   if (input_view.redraw_needed == NO_REDRAW)
  93.     return;
  94.  
  95.   if (input_view.redraw_needed == FULL_REDRAW)
  96.     {
  97.       /* Redraw    the prompt. */ 
  98.       move (row, 0);
  99.       if (input_view.expanded_keymap_prompt)
  100.     {
  101.       addstr (input_view.expanded_keymap_prompt);
  102.       clrtoeol ();
  103.       input_view.redraw_needed = NO_REDRAW;
  104.       return;
  105.     }
  106.       if (input_view.prompt_wid)
  107.     addstr (input_view.prompt);
  108.       pos = input_view.visibility_begin;
  109.     }
  110.   else
  111.     {
  112.       pos = input_view.redraw_needed;
  113.       move (row,
  114.         input_view.prompt_wid + pos - input_view.visibility_begin);
  115.     }
  116.     
  117.   if (   input_view.input_area
  118.       && (input_view.visibility_end >= input_view.visibility_begin)
  119.       && (input_view.visibility_begin < strlen (input_view.input_area->buf)))
  120.     {
  121.       int x;
  122.       for (x = pos; x <= input_view.visibility_end; ++x)
  123.     addch (input_view.input_area->buf[x]);
  124.     }
  125.   clrtoeol ();
  126.   input_view.redraw_needed = NO_REDRAW;
  127. }
  128.  
  129.  
  130. #undef MIN
  131. #define MIN(A,B) (((A) < (B)) ? (A) : (B))
  132.  
  133. #ifdef __STDC__
  134. void
  135. redraw_info (void)
  136. #else
  137. void
  138. redraw_info ()
  139. #endif
  140. {
  141.   if (!input_view.current_info)
  142.     return;
  143.   {
  144.     int ipos = input_view.info_pos;
  145.     int stop = MIN (input_view.current_info->len, scr_lines - 1 + ipos);
  146.     while (ipos < stop)
  147.       {
  148.     move (2 + ipos - input_view.info_pos, 0);
  149.     addstr (input_view.current_info->text[ipos]);
  150.     clrtoeol ();
  151.     ++ipos;
  152.       }
  153.   }
  154.   _io_redraw_input ();
  155. }
  156.  
  157.  
  158. #ifdef __STDC__
  159. static void
  160. _io_fix_input (void)
  161. #else
  162. static void
  163. _io_fix_input ()
  164. #endif
  165. {
  166.   iv_fix_input (&input_view);
  167. }
  168.  
  169. #ifdef __STDC__
  170. static void
  171. _io_move_cursor (void)
  172. #else
  173. static void
  174. _io_move_cursor ()
  175. #endif
  176. {
  177.   iv_move_cursor (&input_view);
  178. }
  179.  
  180. #ifdef __STDC__
  181. static void
  182. _io_erase (int len)
  183. #else
  184. static void
  185. _io_erase (len)
  186.      int len;
  187. #endif
  188. {
  189.   iv_erase (&input_view, len);
  190. }
  191.  
  192. #ifdef __STDC__
  193. static void
  194. _io_insert (int len)
  195. #else
  196. static void
  197. _io_insert (len)
  198.      int len;
  199. #endif
  200. {
  201.   iv_insert (&input_view, len);
  202. }
  203.        
  204. #ifdef __STDC__
  205. static void
  206. _io_over (char * str, int len)
  207. #else
  208. static void
  209. _io_over (str, len)
  210.      char * str;
  211.      int len;
  212. #endif
  213. {
  214.   iv_over (&input_view, len);
  215. }
  216.  
  217.  
  218.  
  219.  
  220.  
  221. #ifdef __STDC__
  222. static void 
  223. _io_display_cell_cursor (void)
  224. #else
  225. static void 
  226. _io_display_cell_cursor ()
  227. #endif
  228. {
  229.   int cell_cursor_row;
  230.   int cell_cursor_col;
  231.   int cc;
  232.   int rr;
  233.   int cwid;
  234.   int n;
  235.   int x, y;
  236.  
  237.   if (input_view.current_info)
  238.     return;
  239.  
  240.   if (   (curow < cwin->screen.lr)
  241.       || (cucol < cwin->screen.lc)
  242.       || (curow > cwin->screen.hr)
  243.       || (cucol > cwin->screen.hc))
  244.     return;
  245.  
  246.   getyx (stdscr, y, x);
  247.   cell_cursor_col = cwin->win_over;
  248.   for (cc = cwin->screen.lc; cc < cucol; cc++)
  249.     cell_cursor_col += get_width (cc);
  250.   cell_cursor_row = cwin->win_down;
  251.   for (rr = cwin->screen.lr; rr < curow; rr++)
  252.     cell_cursor_row += get_height (rr);
  253.   cwid = get_width (cucol);
  254.   if (cwid > cwin->numc)
  255.     cwid = cwin->numc;
  256.   move (cell_cursor_row, cell_cursor_col);
  257.   standout ();
  258.   for (n = cwid; n; n--)
  259. #ifdef A_STANDOUT
  260.     addch (inch () | A_STANDOUT);
  261. #else
  262.     addch (inch ());
  263. #endif
  264.   standend ();
  265.   move (y, x);
  266. }
  267.  
  268. #ifdef __STDC__
  269. static void 
  270. _io_hide_cell_cursor (void)
  271. #else
  272. static void 
  273. _io_hide_cell_cursor ()
  274. #endif
  275. {
  276.   int cc;
  277.   int rr;
  278.   int cell_cursor_row;
  279.   int cell_cursor_col;
  280.   int cwid;
  281.   int n;
  282.   int x, y;
  283.  
  284.   if (input_view.current_info)
  285.     return;
  286.   if (   (curow < cwin->screen.lr)
  287.       || (cucol < cwin->screen.lc)
  288.       || (curow > cwin->screen.hr)
  289.       || (cucol > cwin->screen.hc))
  290.     return;
  291.   getyx (stdscr, y, x);
  292.   cell_cursor_col = cwin->win_over;
  293.   for (cc = cwin->screen.lc; cc < cucol; cc++)
  294.     cell_cursor_col += get_width (cc);
  295.   cell_cursor_row = cwin->win_down;
  296.   for (rr = cwin->screen.lr; rr < curow; rr++)
  297.     cell_cursor_row += get_height (rr);
  298.   cwid = get_width (cucol);
  299.   if (cwid > cwin->numc)
  300.     cwid = cwin->numc;
  301.   move (cell_cursor_row, cell_cursor_col);
  302.   for (n = cwid; n; n--)
  303. #ifdef A_STANDOUT
  304.     addch (inch () & ~A_STANDOUT);
  305. #else
  306.     addch (inch ());
  307. #endif
  308.   move (y, x);
  309. }
  310.  
  311.  
  312.  
  313. /* Functions, etc for dealing with cell contents being displayed
  314.     on top of other cells. */
  315.  
  316. struct slops
  317. {
  318.   int s_alloc, s_used;
  319.   struct s
  320.     {
  321.       CELLREF row, clo, chi;
  322.     } s_b[1];
  323. };
  324.  
  325. #ifdef __STDC__
  326. static void 
  327. flush_slops (VOIDSTAR where)
  328. #else
  329. static void 
  330. flush_slops (where)
  331.      VOIDSTAR where;
  332. #endif
  333. {
  334.   struct slops *s;
  335.  
  336.   s = where;
  337.   if (s)
  338.     s->s_used = 0;
  339. }
  340.  
  341. #ifdef __STDC__
  342. static int 
  343. find_slop (VOIDSTAR where, CELLREF r, CELLREF c, CELLREF *cclp, CELLREF *cchp)
  344. #else
  345. static int 
  346. find_slop (where, r, c, cclp, cchp)
  347.      VOIDSTAR where;
  348.      CELLREF r;
  349.      CELLREF c;
  350.      CELLREF *cclp;
  351.      CELLREF *cchp;
  352. #endif
  353. {
  354.   int n;
  355.   struct slops *s;
  356.  
  357.   s = where;
  358.   if (!s)
  359.     return 0;
  360.   for (n = 0; n < s->s_used; n++)
  361.     {
  362.       if (s->s_b[n].row == r && s->s_b[n].clo <= c && s->s_b[n].chi >= c)
  363.     {
  364.       *cclp = s->s_b[n].clo;
  365.       *cchp = s->s_b[n].chi;
  366.       return 1;
  367.     }
  368.     }
  369.   return 0;
  370. }
  371.  
  372. #ifdef __STDC__
  373. static void 
  374. kill_slop (VOIDSTAR where, CELLREF r, CELLREF clo, CELLREF chi)
  375. #else
  376. static void 
  377. kill_slop (where, r, clo, chi)
  378.      VOIDSTAR where;
  379.      CELLREF r;
  380.      CELLREF clo;
  381.      CELLREF chi;
  382. #endif
  383. {
  384.   int n;
  385.   struct slops *s;
  386.  
  387.   s = where;
  388.   for (n = 0; n < s->s_used; n++)
  389.     {
  390.       if (s->s_b[n].row == r && s->s_b[n].clo == clo && s->s_b[n].chi == chi)
  391.     {
  392.       --(s->s_used);
  393.       s->s_b[n] = s->s_b[s->s_used];
  394.       return;
  395.     }
  396.     }
  397. }
  398.  
  399. #ifdef __STDC__
  400. static void 
  401. set_slop (VOIDSTAR *wherep, CELLREF r, CELLREF clo, CELLREF chi)
  402. #else
  403. static void 
  404. set_slop (wherep, r, clo, chi)
  405.      VOIDSTAR *wherep;
  406.      CELLREF r;
  407.      CELLREF clo;
  408.      CELLREF chi;
  409. #endif
  410. {
  411.   int n;
  412.   struct slops **sp;
  413.  
  414.   sp = (struct slops **) wherep;
  415.   if (!*sp)
  416.     {
  417.       (*sp) = ck_malloc (sizeof (struct slops) + 2 * sizeof (struct s));
  418.       (*sp)->s_alloc = 2;
  419.       (*sp)->s_used = 1;
  420.       n = 0;
  421.     }
  422.   else
  423.     {
  424.       n = (*sp)->s_used++;
  425.       if ((*sp)->s_alloc == n)
  426.     {
  427.       (*sp)->s_alloc = n * 2;
  428.       (*sp) = ck_realloc ((*sp), sizeof (struct slops) + n * 2 * sizeof (struct s));
  429.     }
  430.     }
  431.   (*sp)->s_b[n].row = r;
  432.   (*sp)->s_b[n].clo = clo;
  433.   (*sp)->s_b[n].chi = chi;
  434. }
  435.  
  436. #ifdef __STDC__
  437. static void 
  438. change_slop (VOIDSTAR where,
  439.          CELLREF r, CELLREF olo, CELLREF ohi, CELLREF lo, CELLREF hi)
  440. #else
  441. static void 
  442. change_slop (where, r, olo, ohi, lo, hi)
  443.      VOIDSTAR where;
  444.      CELLREF r;
  445.      CELLREF olo;
  446.      CELLREF ohi;
  447.      CELLREF lo;
  448.      CELLREF hi;
  449. #endif
  450. {
  451.   int n;
  452.   struct slops *s;
  453.  
  454.   s = where;
  455.   for (n = 0; n < s->s_used; n++)
  456.     {
  457.       if (s->s_b[n].row == r && s->s_b[n].clo == olo && s->s_b[n].chi == ohi)
  458.     {
  459.       s->s_b[n].clo = lo;
  460.       s->s_b[n].chi = hi;
  461.       return;
  462.     }
  463.     }
  464. }
  465.  
  466.  
  467. #ifdef __STDC__
  468. static void 
  469. _io_open_display (void)
  470. #else
  471. static void 
  472. _io_open_display ()
  473. #endif
  474. {
  475.   initscr ();
  476.   scrollok (stdscr, 0);
  477. #ifdef HAVE_CBREAK
  478.   cbreak ();
  479. #else
  480.   crmode ();
  481. #endif
  482.   raw ();
  483.   noecho ();
  484.   nonl ();
  485.   /* Must be after initscr() */
  486.   io_init_windows (LINES, COLS - 1, 1, 2, 1, 1, 1, 1);
  487.   info_rows = 1;
  488.   print_width = COLS;        /* Make ascii print width == terminal width. */
  489. }
  490.  
  491. #ifdef __STDC__
  492. void
  493. cont_curses(void)
  494. #else
  495. void
  496. cont_curses()
  497. #endif
  498. {
  499. #ifdef HAVE_CBREAK
  500.   cbreak ();
  501. #else
  502.   crmode ();
  503. #endif
  504.   raw ();
  505.   noecho ();
  506.   nonl ();
  507. }
  508.  
  509.  
  510. #ifdef __STDC__
  511. void
  512. stop_curses(void)
  513. #else
  514. void
  515. stop_curses()
  516. #endif
  517. {
  518. #ifdef HAVE_CBREAK
  519.   nocbreak ();
  520. #else
  521.   nocrmode ();
  522. #endif
  523.   noraw ();
  524.   echo ();
  525.   nl ();
  526.   io_redisp ();
  527. }
  528.  
  529. #ifdef __STDC__
  530. static void 
  531. _io_cellize_cursor (void)
  532. #else
  533. static void 
  534. _io_cellize_cursor ()
  535. #endif
  536. {
  537. }
  538.  
  539. #ifdef __STDC__
  540. static void 
  541. _io_inputize_cursor (void)
  542. #else
  543. static void 
  544. _io_inputize_cursor ()
  545. #endif
  546. {
  547. }
  548.  
  549. #ifdef __STDC__
  550. static void 
  551. _io_redisp (void)
  552. #else
  553. static void 
  554. _io_redisp ()
  555. #endif
  556. {
  557.   if (!term_cursor_claimed)
  558.     {
  559.       _io_redraw_input ();
  560.       if (!(input_view.current_info || input_active ||
  561.         input_view.expanded_keymap_prompt))
  562.     move_cursor_to (cwin, curow, cucol, 0);
  563.       else
  564.     move ((input_view.current_info ? 1 : input), 
  565.           input_view.prompt_wid + input_view.input_cursor -
  566.           input_view.visibility_begin); 
  567.     }
  568.   {
  569.     struct rng * rng = &cwin->screen;
  570.     if (   (curow > rng->hr)
  571.     || (curow < rng->lr)
  572.     || (cucol > rng->hc)
  573.     || (cucol < rng->lc))
  574.       io_recenter_cur_win ();
  575.   }
  576.   refresh ();
  577. }
  578.  
  579. #ifdef __STDC__
  580. static void 
  581. _io_repaint_win (struct window *win)
  582. #else
  583. static void 
  584. _io_repaint_win (win)
  585.      struct window *win;
  586. #endif
  587. {
  588.   io_repaint ();
  589. }
  590.  
  591. #ifdef __STDC__
  592. static void 
  593. _io_repaint (void)
  594. #else
  595. static void 
  596. _io_repaint ()
  597. #endif
  598. {
  599.   CELLREF cc, rr;
  600.   int n, n1;
  601.   CELL *cp;
  602.   struct window *win;
  603.  
  604.   clear ();
  605.   io_fix_input ();
  606.   redrew++;
  607.   if (input_view.current_info)
  608.     {
  609.       redraw_info ();
  610.       return;
  611.     }
  612.  
  613.   for (win = wins; win < &wins[nwin]; win++)
  614.     {
  615.       if (win->lh_wid)
  616.     {
  617.       move (win->win_down - 1, win->win_over - win->lh_wid);
  618.       printw ("#%*d ", win->lh_wid - 2, 1 + win - wins);
  619.       if (win->flags & WIN_EDGE_REV)
  620.         standout ();
  621.       cc = win->screen.lc;
  622.       do
  623.         {
  624.           n = get_width (cc);
  625.           if (n > win->numc)
  626.         n = win->numc;
  627.           if (n > 1)
  628.         {
  629.           char *ptr;
  630.           char buf[30];
  631.  
  632.           if (a0)
  633.             ptr = col_to_str (cc);
  634.           else
  635.             {
  636.               sprintf (buf, "C%u", cc);
  637.               ptr = buf;
  638.             }
  639.           --n;
  640.           n1 = strlen (ptr);
  641.           if (n < n1)
  642.             printw ("%.*s ", n, "###############");
  643.           else
  644.             {
  645.               n1 = (n - n1) / 2;
  646.               printw ("%*s%-*s ", n1, "", n - n1, ptr);
  647.             }
  648.         }
  649.           else if (n == 1)
  650.         addstr ("#");
  651.         }
  652.       while (cc++ < win->screen.hc);
  653.  
  654.       rr = win->screen.lr;
  655.       n = win->win_down;
  656.       do
  657.         {
  658.           n1 = get_height (rr);
  659.           if (n1)
  660.         {
  661.           move (n, win->win_over - win->lh_wid);
  662.           if (a0)
  663.             printw ("%-*d ", win->lh_wid - 1, rr);
  664.           else
  665.             printw ("R%-*d", win->lh_wid - 1, rr);
  666.           n += n1;
  667.         }
  668.         }
  669.       while (rr++ < win->screen.hr);
  670.  
  671.       if (win->flags & WIN_EDGE_REV)
  672.         standend ();
  673.     }
  674.       flush_slops (win->win_slops);
  675.       find_cells_in_range (&(win->screen));
  676.       while (cp = next_row_col_in_range (&rr, &cc))
  677.     if (GET_TYP (cp))
  678.       io_pr_cell_win (win, rr, cc, cp);
  679.     }
  680.   if (!(cp = find_cell (curow, cucol)) || !GET_TYP (cp))
  681.     io_display_cell_cursor ();
  682.   input_view.redraw_needed = FULL_REDRAW;
  683.   _io_redraw_input ();
  684.   io_update_status ();
  685. }
  686.  
  687. #ifdef __STDC__
  688. static void 
  689. _io_close_display (void)
  690. #else
  691. static void 
  692. _io_close_display ()
  693. #endif
  694. {
  695.   clear ();
  696.   refresh ();
  697.   (void) endwin ();
  698. }
  699.  
  700. /* This is extern because it was convenient to leave the signal */
  701. /* handler that increments it in io_term.c */
  702. int input_avail_val;
  703.  
  704. #ifdef __STDC__
  705. static int 
  706. _io_input_avail (void)
  707. #else
  708. static int 
  709. _io_input_avail ()
  710. #endif
  711. {
  712.   return (FD_ISSET (0, &read_pending_fd_set)
  713.       || FD_ISSET (0, &exception_pending_fd_set));
  714. }
  715.  
  716. #ifdef __STDC__
  717. static void 
  718. _io_scan_for_input (int block)
  719. #else
  720. static void 
  721. _io_scan_for_input (block)
  722.      int block;
  723. #endif
  724. {
  725.   /* This function only exists because X kbd events don't generate */
  726.   /* SIGIO. Under curses, the SIGIO hander does the work of this */
  727.   /* function. */
  728. }
  729.  
  730. #ifdef __STDC__
  731. static void 
  732. _io_wait_for_input (void)
  733. #else
  734. static void 
  735. _io_wait_for_input ()
  736. #endif
  737. {
  738.   pause ();
  739. }
  740.  
  741. #ifdef __STDC__
  742. static int 
  743. _io_read_kbd (VOLATILE char *buf, int size)
  744. #else
  745. static int 
  746. _io_read_kbd (buf, size)
  747.      VOLATILE char *buf;
  748.      int size;
  749. #endif
  750. {
  751.   int r = read (0, buf, size);
  752.   FD_CLR (0, &read_pending_fd_set);
  753.   FD_CLR (0, &exception_pending_fd_set);
  754.   return r;
  755. }
  756.  
  757.  
  758. #if defined(SIGIO)
  759.  
  760.  
  761. #ifdef __STDC__
  762. static void 
  763. _io_nodelay (int delayp)
  764. #else
  765. static void 
  766. _io_nodelay (delayp)
  767.      int delayp;
  768. #endif
  769. {
  770.   panic ("Trying to curses nodelay on a system with SIGIO.");
  771. }
  772.  
  773. #else
  774.  
  775. #ifdef __STDC__
  776. static void 
  777. _io_nodelay (int delayp)
  778. #else
  779. static void 
  780. _io_nodelay (delayp)
  781.      int delayp;
  782. #endif
  783. {
  784.   nodelay (stdscr, delayp);
  785. }
  786.  
  787. #endif
  788.  
  789. #ifdef __STDC__
  790. static int 
  791. _io_getch (void)
  792. #else
  793. static int 
  794. _io_getch ()
  795. #endif
  796. {
  797.   char ch;
  798.   return ((io_read_kbd (&ch, 1) != 1)
  799.       ? EOF
  800.       : ch);
  801. }
  802.  
  803.  
  804. #ifdef __STDC__
  805. static int 
  806. _io_get_chr (char *prompt)
  807. #else
  808. static int 
  809. _io_get_chr (prompt)
  810.      char *prompt;
  811. #endif
  812. {
  813.   int x;
  814.   mvaddstr (input, 0, prompt);
  815.   clrtoeol ();
  816.   topclear = 2;
  817.   refresh ();
  818.   ++term_cursor_claimed;
  819.   x = get_chr ();
  820.   --term_cursor_claimed;
  821.   return x;
  822. }
  823.  
  824. #define BUFFER 10
  825.  
  826. #ifdef __STDC__
  827. static void 
  828. local_putchar (int ch)
  829. #else
  830. static void 
  831. local_putchar (ch)
  832.      int ch;
  833. #endif
  834. {
  835.   (void) putc (ch, stdout);
  836.   /* (void)putchar(ch); */
  837. }
  838.  
  839. #ifdef __STDC__
  840. static void
  841. local_puts (char *s)
  842. #else
  843. static void
  844. local_puts (s)
  845.     char *s;
  846. #endif
  847. {
  848.    (void) tputs (s, 1, (int (*)()) local_putchar);
  849. }
  850.  
  851. #ifdef __STDC__
  852. static void 
  853. _io_bell (void)
  854. #else
  855. static void 
  856. _io_bell ()
  857. #endif
  858. {
  859. #ifndef HAVE_GETCAP
  860.   putchar ('\007');
  861. #else
  862.   static char *vb;
  863.   static int called = 0;
  864.  
  865.   if (!called)
  866.     {
  867.       called++;
  868.       vb = getcap ("vb");
  869.     }
  870.   if (vb)
  871.     {
  872.       local_puts (vb);
  873.     }
  874.   else
  875.     {
  876.       local_putchar ('\007');
  877.     }
  878. #endif
  879. }
  880.  
  881.  
  882. #if __STDC__
  883. static void
  884. move_cursor_to (struct window *win, CELLREF r, CELLREF c, int dn)
  885. #else
  886. static void
  887. move_cursor_to (win, r, c, dn)
  888.      struct window *win;
  889.      CELLREF r;
  890.      CELLREF c;
  891.      int dn;
  892. #endif
  893. {
  894.   int cc;
  895.   int cell_cursor_col;
  896.   int rr;
  897.   int cell_cursor_row;
  898.   
  899.   cell_cursor_col = win->win_over;
  900.   for (cc = win->screen.lc; cc < c; cc++)
  901.     cell_cursor_col += get_width (cc);
  902.   cell_cursor_row = win->win_down + dn;
  903.   for (rr = win->screen.lr; rr < r; rr++)
  904.     cell_cursor_row += get_height (rr);
  905.   move (cell_cursor_row, cell_cursor_col);
  906. }
  907.  
  908. #ifdef __STDC__
  909. static void
  910. _io_update_status (void)
  911. #else
  912. static void
  913. _io_update_status ()
  914. #endif
  915. {
  916.   CELL *cp;
  917.   char *dec;
  918.   char *ptr;
  919.   static char hmbuf[40];
  920.   int wid;
  921.   int plen;
  922.   int dlen;
  923.   int yy, xx;
  924.   
  925.   if (!user_status || input_view.current_info)
  926.     return;
  927.   getyx (stdscr, yy, xx);
  928.   move (status, 0);
  929.   wid = COLS - 2;
  930.   
  931.   if (mkrow != NON_ROW)
  932.     {
  933.       struct rng r;
  934.       
  935.       addch ('*');
  936.       --wid;
  937.       set_rng (&r, curow, cucol, mkrow, mkcol);
  938.       ptr = range_name (&r);
  939.     }
  940.   else
  941.     ptr = cell_name (curow, cucol);
  942.   
  943.   addstr (ptr);
  944.   wid -= strlen (ptr);
  945.   
  946.   if (how_many != 1)
  947.     {
  948.       sprintf (hmbuf, " {%d}", how_many);
  949.       addstr (hmbuf);
  950.       wid -= strlen (hmbuf);
  951.     }
  952.   
  953.   if ((cp = find_cell (curow, cucol)) && cp->cell_formula)
  954.     {
  955.       dec = decomp (curow, cucol, cp);
  956.       dlen = strlen (dec);
  957.     }
  958.   else
  959.     {
  960.       dec = 0;
  961.       dlen = 0;
  962.     }
  963.   
  964.   ptr = cell_value_string (curow, cucol);
  965.   plen = strlen (ptr);
  966.   
  967.   if (dec)
  968.     {
  969.       wid -= 4;
  970.       if (dlen + plen > wid)
  971.     {
  972.       if (plen + 3 > wid)
  973.         printw (" %.*s... [...]", wid - 6, ptr);
  974.       else
  975.         printw (" %s [%.*s...]", ptr, wid - plen - 3, dec);
  976.     }
  977.       else
  978.     printw (" %s [%s]", ptr, dec);
  979.       decomp_free ();
  980.     }
  981.   else if (plen)
  982.     {
  983.       --wid;
  984.       if (plen > wid)
  985.     printw (" %.*s...", wid - 3, ptr);
  986.       else
  987.     printw (" %s", ptr);
  988.     }
  989.   
  990.   clrtoeol ();
  991.   move (yy, xx);
  992. }
  993.  
  994. extern int auto_recalc;
  995.  
  996. #ifdef __STDC__
  997. static void
  998. _io_clear_input_before (void)
  999. #else
  1000. static void
  1001. _io_clear_input_before ()
  1002. #endif
  1003. {
  1004.   textout = 0;
  1005.   if (topclear == 2)
  1006.     {
  1007.       move (input, 0);
  1008.       clrtoeol ();
  1009.       topclear = 0;
  1010.     }
  1011.   move (0, 0);
  1012. }
  1013.  
  1014. #ifdef __STDC__
  1015. static void
  1016. _io_clear_input_after (void)
  1017. #else
  1018. static void
  1019. _io_clear_input_after ()
  1020.   #endif
  1021. {
  1022.   if (topclear)
  1023.     {
  1024.       move (input, 0);
  1025.       clrtoeol ();
  1026.       topclear = 0;
  1027.     }
  1028. }
  1029.  
  1030.  
  1031. #if __STDC__
  1032. static void
  1033. _io_pr_cell_win (struct window *win, CELLREF r, CELLREF c, CELL *cp)
  1034. #else
  1035. static void
  1036. _io_pr_cell_win (win, r, c, cp)
  1037.      struct window *win;
  1038.      CELLREF r;
  1039.      CELLREF c;
  1040.      CELL *cp;
  1041. #endif
  1042. {
  1043.   int glowing;
  1044.   int lenstr;
  1045.   int j;
  1046.   int wid, wwid;
  1047.   int hgt;
  1048.   char *ptr;
  1049.   int yy, xx;
  1050.   
  1051.   if (input_view.current_info)
  1052.     return;
  1053.  
  1054.   wid = get_width (c);
  1055.   if (!wid)
  1056.     return;
  1057.   if (wid > win->numc)
  1058.     wid = win->numc;
  1059.   hgt = get_height (r);
  1060.   if (!hgt)
  1061.     return;
  1062.   if (hgt > win->numr)
  1063.     hgt = win->numr;
  1064.   
  1065.   getyx (stdscr, yy, xx);
  1066.   glowing = (r == curow && c == cucol && win == cwin);
  1067.   ptr = print_cell (cp);
  1068.   move_cursor_to (win, r, c, 0);
  1069.   if (glowing)
  1070.     standout ();
  1071.   j = GET_JST (cp);
  1072.   if (j == JST_DEF)
  1073.     j = default_jst;
  1074.   lenstr = strlen (ptr);
  1075.   
  1076.   if (lenstr <= wid - 1)
  1077.     {
  1078.       CELLREF ccl, cch;
  1079.       
  1080.       if (j == JST_LFT)
  1081.     printw ("%-*.*s", wid, wid - 1, ptr);
  1082.       else if (j == JST_RGT)
  1083.     printw ("%*.*s ", wid - 1, wid - 1, ptr);
  1084.       else if (j == JST_CNT)
  1085.     {
  1086.       wwid = (wid - 1) - lenstr;
  1087.       printw ("%*s%*s ", (wwid + 1) / 2 + lenstr, ptr, wwid / 2, "");
  1088.     }
  1089. #ifdef TEST
  1090.       else
  1091.     panic ("Unknown justification");
  1092. #endif
  1093.       if (glowing)
  1094.     standend ();
  1095.       
  1096.       if (lenstr == 0 && c > win->screen.lc
  1097.       && find_slop (win->win_slops, r, c - 1, &ccl, &cch))
  1098.     {
  1099.       CELLREF ccdl, ccdh;
  1100.       
  1101.       if (find_slop (win->win_slops, r, c, &ccdl, &ccdh) && ccdl == c)
  1102.         {
  1103.           kill_slop (win->win_slops, r, ccdl, ccdh);
  1104.           for (; ccdh != ccdl; --ccdh)
  1105.         if (ccdh != c && (wwid = get_width (ccdh)))
  1106.           {
  1107.             move_cursor_to (win, r, ccdh, 0);
  1108.             printw ("%*s", wwid, "");
  1109.           }
  1110.         }
  1111.       kill_slop (win->win_slops, r, ccl, cch);
  1112.       io_pr_cell (r, ccl, find_cell (r, ccl));
  1113.     }
  1114.       else if (find_slop (win->win_slops, r, c, &ccl, &cch))
  1115.     {
  1116.       kill_slop (win->win_slops, r, ccl, cch);
  1117.       for (; cch != ccl; --cch)
  1118.         if (cch != c && (wwid = get_width (cch)))
  1119.           {
  1120.         move_cursor_to (win, r, cch, 0);
  1121.         printw ("%*s", wwid, "");
  1122.           }
  1123.       io_pr_cell (r, ccl, find_cell (r, ccl));
  1124.     }
  1125.     }
  1126.   else
  1127.     {
  1128.       CELLREF cc = c;
  1129.       CELL *ccp;
  1130.       CELLREF ccl, cch;
  1131.       
  1132.       for (wwid = wid; lenstr > wwid - 1; wwid += get_width (cc))
  1133.     {
  1134.       if (++cc > win->screen.hc
  1135.           || ((ccp = find_cell (r, cc))
  1136.           && GET_TYP (ccp)
  1137.           && (GET_FMT (ccp) != FMT_HID
  1138.               || (GET_FMT (ccp) == FMT_DEF
  1139.               && default_fmt != FMT_HID))))
  1140.         {
  1141.           --cc;
  1142.           break;
  1143.         }
  1144.     }
  1145.       
  1146.       if (lenstr > wwid - 1)
  1147.     if (GET_TYP (cp) == TYP_FLT)
  1148.       ptr = adjust_prc (ptr, cp, wwid - 1, wid - 1, j);
  1149.     else if (GET_TYP (cp) == TYP_INT)
  1150.       ptr = (char *) numb_oflo;
  1151.       
  1152.       if (wwid == 1)
  1153.     {
  1154.       addch (' ');
  1155.       if (glowing)
  1156.         standend ();
  1157.     }
  1158.       else if (wwid == wid)
  1159.     {
  1160.       printw ("%-*.*s ", wwid - 1, wwid - 1, ptr);
  1161.       if (glowing)
  1162.         standend ();
  1163.     }
  1164.       else if (glowing)
  1165.     {
  1166.       printw ("%.*s", wid, ptr);
  1167.       standend ();
  1168.       printw ("%-*.*s ", wwid - wid - 1, wwid - wid - 1, ptr + wid);
  1169.     }
  1170.       else if (r == curow && (cucol > c && cucol <= cc))
  1171.     {
  1172.       CELLREF ctmp;
  1173.       int w_left;
  1174.       int w_here;
  1175.       
  1176.       w_left = wid;
  1177.       for (ctmp = c + 1; ctmp < cucol; ctmp++)
  1178.         w_left += get_width (ctmp);
  1179.       printw ("%.*s", w_left, ptr);
  1180.       standout ();
  1181.       w_here = get_width (cucol);
  1182.       if (wwid > w_left + w_here)
  1183.         {
  1184.           printw ("%-*.*s", w_here, w_here, ptr + w_left);
  1185.           standend ();
  1186.           printw ("%-*.*s ",
  1187.               wwid - (w_left + w_here) - 1, wwid - (w_left + w_here) - 1,
  1188.               ptr + w_left + w_here);
  1189.         }
  1190.       else
  1191.         {
  1192.           printw ("%-*.*s", w_here, w_here - 1, ptr + w_left);
  1193.           standend ();
  1194.         }
  1195.     }
  1196.       else
  1197.     printw ("%-*.*s ", wwid - 1, wwid - 1, ptr);
  1198.       
  1199.       if (find_slop (win->win_slops, r, c, &ccl, &cch))
  1200.     {
  1201.       change_slop (win->win_slops, r, ccl, cch, c, cc);
  1202.       for (; cch > cc; --cch)
  1203.         if (wwid = get_width (cch))
  1204.           {
  1205.         move_cursor_to (win, r, cch, 0);
  1206.         printw ("%*s", wwid, "");
  1207.           }
  1208.       for (cch = c - 1; cch > ccl; --cch)
  1209.         if (wwid = get_width (cch))
  1210.           {
  1211.         move_cursor_to (win, r, cch, 0);
  1212.         printw ("%*s", wwid, "");
  1213.           }
  1214.       if (ccl != c)
  1215.         io_pr_cell (r, ccl, find_cell (r, ccl));
  1216.     }
  1217.       else
  1218.     set_slop ((VOIDSTAR *) (&(win->win_slops)), r, c, cc);
  1219.     }
  1220.   if ((hgt > 1) && display_formula_mode)
  1221.     {
  1222.       move_cursor_to (win, r, c, 1);
  1223.       ptr = decomp (r, c, cp);
  1224.       printw ("%.*s ", wid - 1, ptr);
  1225.       decomp_free ();
  1226.     }
  1227.   if (glowing)
  1228.     io_update_status ();
  1229.   move (yy, xx);
  1230. }
  1231.  
  1232.  
  1233.  
  1234. #ifdef __STDC__
  1235. static void
  1236. _io_flush (void)
  1237. #else
  1238. static void
  1239. _io_flush ()
  1240. #endif
  1241. {
  1242.   refresh ();
  1243. }
  1244.  
  1245.  
  1246.  
  1247.  
  1248. #ifdef __STDC__
  1249. void
  1250. tty_graphics (void)
  1251. #else
  1252. void
  1253. tty_graphics ()
  1254. #endif
  1255. {
  1256.  
  1257.   FD_SET (0, &read_fd_set);
  1258.   FD_SET (0, &exception_fd_set);
  1259.   IO_SETUP;
  1260. }
  1261.